import React, { Component } from 'react';
import { Modal, Tooltip, message, Button } from 'antd';
import PropTypes from 'prop-types';
import moment from 'moment';
import _ from 'lodash';
import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { addOneday } from '@api/task';
import './index.less';
import OnedayDetectionTarget from '@components/oneday-detection-target';
import TaskCommonFields from '@components/task-common-fields';
import isClusterModel from '@components/is-cluster-model';
const prefixCls = 'oneday-modal';

class OnedayModal extends Component {
  static defaultState = {
    adding: false,
    radioValue: 'affected',
    ignoreIpsError: '',
    ignoreType: {
      whitelist: true,
      custom: false
    },
    customIgnoreTarget: [],
    timeError: '',
    timing: {},
    startAt: '',
    endAt: '',
    priority: 'middle'
  };
  constructor(props) {
    super(props);
    this.state = { ...OnedayModal.defaultState };
  }

  static getDerivedStateFromProps(props) {
    if (!props.modalVisible) {
      return _.cloneDeep(OnedayModal.defaultState);
    }
    return null;
  }

  getOnedayParams = () => {
    const { radioValue } = this.state;
    const { onedays } = this.props;
    const params = {};
    let errorMsgOneday = '';
    let selectedOnedays;
    if (radioValue === 'affected') {
      selectedOnedays = _.filter(
        onedays,
        row => _.get(row, 'affectedSiteCount.real') || _.get(row, 'affectedSiteCount.suspect')
      );
      if (_.isEmpty(onedays)) {
        errorMsgOneday = '您选择的漏洞当前影响资产数皆为0，请更换检测目标!';
        return { errorMsgOneday };
      }
    } else {
      selectedOnedays = onedays;
    }

    params.oneday = { onedayDetailOids: _.map(selectedOnedays, '_id'), queryType: 'list' };

    let targetDesc;
    if (radioValue === 'affected') {
      targetDesc = '受影响的资产';
      params.target = { queryType: 'affectedByOnedayDetail' };
    } else {
      targetDesc = '全部资产';
      params.target = { queryType: 'allSite' };
    }

    const onedaysLength = _.get(onedays, 'length');
    const affectedByOnedayLength = _.get(_.map(selectedOnedays, '_id'), 'length');
    const onedayDesc = `${_.get(onedays, ['0', 'name'])}${
      onedaysLength > 1 ? `等${affectedByOnedayLength}条1DAY` : ''
    }`;
    params.name = `${onedayDesc}_${targetDesc}_${moment().format('YYYYMMDDHHmmss')}`;

    return { params };
  };

  onOk = async () => {
    const { modules, isCluster } = this.props;
    if (!modules.includes('detection')) {
      return message.info('演示版本不能下发任务，请联系ZoomEye BE团队获取正式版本');
    }
    await isClusterModel();
    const {
      timing: timeRange,
      ignoreType,
      startAt,
      endAt,
      customIgnoreTarget,
      priority,
      errorMsg,
      scanNodes
    } = this.state;

    const { params, errorMsgOneday } = this.getOnedayParams();
    // 如果是集群 node默认为auto interface_type默认为'work'
    if (isCluster) {
      params.node = scanNodes;

      params.interface_type = 'work';
    } else {
      params.node = 'local';
    }
    if (errorMsgOneday || errorMsg) {
      message.warning(errorMsgOneday || errorMsg);
      return;
    }

    let newIgnoreType = [];
    if (ignoreType.whitelist) {
      newIgnoreType.push('whiteList');
    }
    if (ignoreType.custom) {
      params.customIgnoreTarget = customIgnoreTarget;
      if (!customIgnoreTarget.length) {
        message.warning('勾选了自定义忽悠目标，没有填写对应目标');
        return;
      }
      newIgnoreType.push('custom');
    }
    if (newIgnoreType.length) {
      params.ignoreType = newIgnoreType;
    }

    let timing = _.cloneDeep(timeRange);
    if (timing) {
      startAt && (timing.startAt = startAt.format('YYYY-MM-DD HH:mm:ss'));
      endAt && (timing.endAt = endAt.format('YYYY-MM-DD HH:mm:ss'));
      if (timing.dailyStart) {
        timing.dailyStart = timing.dailyStart.format('HH:mm');
      } else {
        delete timing.dailyStart;
      }
      if (timing.dailyEnd) {
        timing.dailyEnd = timing.dailyEnd.format('HH:mm');
      } else {
        delete timing.dailyEnd;
      }
      params.timing = timing;
    }

    if (priority) {
      params.priority = priority;
    }
    this.setState({ adding: true });

    addOneday({ fields: params })
      .then(() => {
        message.success('下发检测成功');
      })
      .catch(({ type, message: messageString }) => {
        if (type === 'parsed') {
          message.error(messageString);
        } else {
          message.error('下发检测失败');
        }
      })
      .finally(() => {
        this.setState({ adding: false }, this.props.onClickSubmit);
      });
  };

  onTargetChange = e => {
    this.setState({
      radioValue: e.target.value
    });
  };

  getShowOneDays = () => {
    const { modalType = 'single', onedays } = this.props;
    const filterOnedays =
      modalType === 'single' ? onedays : _.filter(onedays, row => _.get(row, 'poc'));
    const affectedSite = _.filter(
      filterOnedays,
      row => _.get(row, 'affectedSiteCount.real') || _.get(row, 'affectedSiteCount.suspect')
    );
    return {
      onedays: filterOnedays,
      affectedSiteCount: _.get(affectedSite, 'length', 0)
    };
  };

  onCommonFieldChange = commonFields => {
    const fields = _.pick(commonFields, [
      'startAt',
      'endAt',
      'timing',
      'errorMsg',
      'priority',
      'ignoreType',
      'customIgnoreTarget',
      'scanNodes'
    ]);
    this.setState({ ...fields });
  };

  render() {
    const { radioValue, adding } = this.state;
    const { modalVisible = false, modalType = 'single' } = this.props;
    const { onedays, affectedSiteCount } = this.getShowOneDays();
    return (
      <div className="oneday-modal">
        <Modal
          maskClosable={false}
          visible={modalVisible}
          title="1DAY检测"
          width={570}
          closable={false}
          className={`${prefixCls}-modal`}
          footer={[
            <Button key="back" onClick={() => this.props.changeModalVisible(false)}>
              取消
            </Button>,
            <Button
              disabled={!affectedSiteCount && radioValue !== 'all'}
              key="submit"
              type="primary"
              loading={adding}
              onClick={this.onOk}
              className="button-forwards"
            >
              确定
            </Button>
          ]}
          destroyOnClose
        >
          <div className={`${prefixCls}-number`}>
            此次使用漏洞插件数量
            <span>{onedays.length}个</span>
          </div>

          <div className={`${prefixCls}-item`}>
            <div className={`${prefixCls}-item-sub-title`}>检测策略</div>
            <div className={`${prefixCls}-item-onedays`}>
              {onedays.map(item => {
                const name = _.get(item, 'name', '');
                return (
                  <Tooltip title={name} key={name}>
                    <div className="oneday-tag">{name}</div>
                  </Tooltip>
                );
              })}
            </div>
          </div>

          <OnedayDetectionTarget
            handleTargetChange={this.onTargetChange}
            radioValue={radioValue}
            modalType={modalType}
          />
          {!affectedSiteCount && radioValue === 'affected' && (
            <div style={{ color: 'red', marginBottom: '16px' }}>
              您所选检测策略可影响资产数量皆为 0，请更换检测目标
            </div>
          )}
          <TaskCommonFields onCommonFieldChange={this.onCommonFieldChange} prefixCls={prefixCls} />
        </Modal>
      </div>
    );
  }
}

OnedayModal.propTypes = {
  changeModalVisible: PropTypes.func,
  modalVisible: PropTypes.bool,
  modalType: PropTypes.string,
  onClickSubmit: PropTypes.func,
  adding: PropTypes.bool,
  onedays: PropTypes.array,
  modules: PropTypes.array,
  history: PropTypes.object,
  isCluster: PropTypes.object
};

const mapStateToProps = state => {
  return {
    modules: _.get(state, 'auth.cert.modules', []),
    isCluster: _.get(state, 'auth.cert.is_cluster', false)
  };
};

export default withRouter(connect(mapStateToProps)(OnedayModal));
